﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Tools;

namespace JHStock
{
    public class JHConfig
    {
        public JHConfig(string jsconfigfilename)
        {
            _Cloned = false;
            IsUpdateAllrunning = false;
            _ready = false;
            _jsconfig = new JSConfig();
            _itemShows = null;
            _updatefin = null;
            if (File.Exists(jsconfigfilename))
                _jsconfig.Load(jsconfigfilename);
        }
        private JHConfig()
        {
           
            IsUpdateAllrunning = false;
            _ready = false;
            _jsconfig = new JSConfig();
            _itemShows = null;
            _updatefin = null;
        }
        public JHConfig Clone(string path, List<Stock> list)
        {
            JHConfig jhcfg = new JHConfig();
            jhcfg._Cloned = true;
            jhcfg._jsconfig = Jsconfig.Clone(path);
            jhcfg._ready = _ready;
            jhcfg._stocksconfig = new StocksConfig(db, jhcfg._jsconfig.pathconfig);
            jhcfg._stocks = new JHStock.Stocks(jhcfg._stocksconfig, list);
            jhcfg._stocksdatas = new StocksDatas(jhcfg);
            jhcfg._itemShows = new ItemShows( jhcfg._stocks);
            return jhcfg;
        }
        public bool CheckReady() // throw Exception
        {
            if (_jsconfig.CheckPath())
            {
                if (InitStocks())
                {
                    _stocksdatas = new StocksDatas(this);
                    _ready = true;
                }
            }
            return _ready;
        }
        private bool InitStocks()
        {
            try
            {
                if (Jsconfig.pathconfig != null && File.Exists(Jsconfig.pathconfig.dbpath))
                {
                    db = new Db.ConnDb(Jsconfig.pathconfig.dbpath);
                    _stocksconfig = new StocksConfig(db, Jsconfig.pathconfig);
                    _stocks = new Stocks(_stocksconfig);
                }
                else
                {
                    ErrMsg = "数据库文件不存在，请更正后重试";
                    return false;
                }
            }
            catch (Exception e)
            {
                ErrMsg = "读取数据库文件时发生错误，代码为：" + e.Message + "请更正后重试";
                return false;
            }
            return true;
        }
        private void InitItemShows()
        {
            if (_itemShows == null)
            {
                _itemShows = new ItemShows(_stocks);
            }
        }
        private void InitUpdateFin()
        {
            if (_updatefin == null)
            {
                _updatefin = new Update.UpdateFin(_stocks);
            }
        }

        public Update.UpdateFin Updatefin { get{ InitUpdateFin(); return _updatefin;}}

        public void SetKDataType(string datatype)
        {
            _stocksdatas.SetActiveKdataType(datatype);
        }

        public StocksData DaylyStocksData()
        {
            return _stocksdatas.GetStocksData("dayly");
        }
        public StocksData ActiveStocksData { get { return _stocksdatas.ActiveStocksData(); } }
        public JSConfig Jsconfig { get { return _jsconfig; } }
        public Stocks Stocks{ get { return _stocks; } }
        public ItemShows Itemshows { get { InitItemShows(); return _itemShows; } }

        public List<string> TableNames { get { return DataTableTools.ReadTableNames(db); } }
        public string ErrMsg { get; set; }
        private JSConfig _jsconfig;
        private bool _ready;
        private Stocks _stocks;
        private ItemShows _itemShows;
        //Unuse
        private Db.ConnDb db;
        private StocksConfig _stocksconfig;
        private StocksDatas _stocksdatas;
        private Update.UpdateFin _updatefin;
        //
        private bool _Cloned;
        public bool Cloned { get { return _Cloned; } }
        public bool IsUpdate { get { return IsUpdateAllrunning && IsUpdateFin; } }
        public bool IsUpdateAllrunning{ get; set; } 
        public bool IsUpdateFin { get; set; }
        public void SetCwfxType(bool reportbyyeas)
        {
            Updatefin.SetCwfxType(reportbyyeas);
            Jsconfig.pathconfig.SetCwfxType(reportbyyeas);
        }
    }
    public class StocksDatas
    {

        public StocksDatas(JHConfig jHConfig)
        {            
            this.Jhconfig = jHConfig;
            _activeindex = 0;
            Init();
        }
        private void Init()
        {
            _stocksdatalist =new StocksData[8];
            _indexdic = new Dictionary<string, int>();
            _kdatatypenames = new List<string>();
            List<string> itemsindex = new List<string>() { "day", "week", "month", "m1", "m5", "m15", "m30", "m60" };
            for (int i = 0; i < itemsindex.Count; i++)
            {
                _indexdic[itemsindex[i]] = i;
                _indexdic[itemsindex[i] + "ly"] = i;
                _kdatatypenames.Add( itemsindex[i] + "ly");
            }
        }
        public StocksData GetStocksData(string kdatatype)
        {
            if(_indexdic.ContainsKey(kdatatype.ToLower()))
            {
                int index = _indexdic[kdatatype.ToLower()];
                if(_stocksdatalist[index] == null)
                    _stocksdatalist[index] = new StocksData(Jhconfig, kdatatype.ToLower());
                return _stocksdatalist[index];
            }
            return null;                
        }
        public StocksData ActiveStocksData()
        {
            if (_stocksdatalist[_activeindex] == null)
            {
                _stocksdatalist[_activeindex] = new StocksData(Jhconfig,ActiveKdataType());
            }
            return _stocksdatalist[_activeindex];
        }
        public void SetActiveKdataType(string datatype)
        {
            if (_indexdic.ContainsKey(datatype))
                _activeindex = _indexdic[datatype];
        }
        public String ActiveKdataType()
        {
            return _kdatatypenames[_activeindex];
        }

        private JHConfig Jhconfig;
        private int _activeindex;

        private StocksData[] _stocksdatalist;
        private List<string> _kdatatypenames;
        private Dictionary<string, int> _indexdic;

    }
    public class StocksConfig
    {
        public StocksConfig(Db.ConnDb db, PathConfig pathConfig)
        {
            this.Db = db;
            this.Pathconfig = pathConfig;
            Tempconfig  = new TempConfig();
            Stateconfig = new StateConfig();
        }
        public Db.ConnDb Db{ get; set; }
        public PathConfig Pathconfig{ get; set; }
        public TempConfig Tempconfig{ get; set; }
        public StateConfig Stateconfig{ get; set; }
    }
    public class StateConfig
    {
        public bool Debug { get; set; }
        public bool UpdateDebug { get; set; }
        public string ErrMsg { get; set; }
    }
    public class ItemShows
    {
        private Stocks _stocks;
        public ItemShows(Stocks _stocks)
        {
            this._stocks = _stocks;
            InitItems();
        }
        private void InitItems()
        {
            itemsShow = new List<string>();
            items = new List<string>();
            items.AddRange(
                _stocks.stocks.Select(
                    s => s.Code + "-" + s.Name + "(" + s.PYCode + ")").ToArray());
        }
        public List<string> GetLocalStockNames()
        {
            string importtext = "600221";
            if (File.Exists("select.txt"))
                importtext = File.ReadAllText("select.txt").Trim();
            List<string> find = items.FindAll(s => importtext.Contains(s.Substring(2, 6)));  //s.Contains(importtext.ToUpper())           
            return find;
        }
        public List<Stock> StocksByItemsShow(bool ifemptyall = false)
        {
            List<Stock> ls = new List<Stock>();
            foreach (string str in itemsShow)
            {
                Stock s = _stocks.StockByNumCode(str.Substring(2, 6));/////
                if(s!=null)
                ls.Add(s);
            }
            if (ls.Count == 0 && ifemptyall)
                return _stocks.stocks;
            return ls;
        }
        public List<string> Items { get { return items; } }
        public List<string> ItemsShow { get { return itemsShow; } }
        
        private List<string> items;
        private List<string> itemsShow;
    }
}
